GrossFullWithdrawalWithAllocations
This assignment accepts allocation instructions and operates as two virtual layers where the all cash value of funds in the first layer are completely depleted before progressing to funds in the second layer. The first layer operates on the provided allocation which is limited to a percent allocation method. Funds in the second layer are all the other policy funds not in the allocation. If processing reaches the second layer, assignment of the money type values is distributed via a prorata formula. The total removed from the funds must match the sum of the MoneyTypes and the sum of the cash values removed from the fund's deposits must match the expected fund removal amounts. MoneyType values must be negative.
- The assignment's "remaining MoneyType value" is set to the sum total of the MoneyTypes.
- For funds in the allocation (first virtual layer),
- The layer's "remaining MoneyType value" is the lesser of the assignment's "remaining MoneyType value" and the total value of all fund values in this layer.
- Order the policy's funds in this layer.
- For each fund,
- Calculate the "removal amount" as the "remaining MoneyType value" X allocation percent. Round the result to the currency definition.
- The last fund is adjusted so that the sum total of fund removals is equal to the layer's "remaining MoneyType value".
- if the "removal amount" is greater than the fund's cash value, report an error.
- If no error,
- For each fund in the layer in reverse order,
- If the fund's "removal amount" is greater than the fund's value, accumulate the difference and make "removal amount" equal to the fund's value. This is the "accumulated difference".
- If the fund's value is greater than its "removal amount", add as much of the "accumulated difference" to the "removal amount" as the fund's value will allow and adjust the "accumulated difference" by what the fund's value allowed.
- By the end of the loop, error if the "accumulated difference" is greater than 0.
- For each fund in the layer in original order,
- Calculate "allocation percent" as "removal amount" / "remaining MoneyType value".
- For the last fund, "allocation percent" is adjusted so the sum of all "allocation percents" is 1.
- For each non-zero value MoneyType in the order configured,
- For each fund in this layer in original order,
- if the last non-zero value MoneyType
- Calculate the amount to remove from the fund as the difference of fund's "removal amount" and the fund's "distributed amount".
- if the last non-zero value MoneyType
- otherwise,
- Calculate the fund's "removal amount" per MoneyType and round to the currency definition: "allocation percent" X MoneyType value.
- The last fund is adjusted so the sum of the "removal amount" values equals the MoneyType value.
- Accumulate the "removal amount". This is the "distributed amount".
- For each fund in this layer in original order,
- The assignment's "remaining MoneyType value" is reduced by the layer's "remaining MoneyType value".
- For each fund in the layer in reverse order,
- If the "remaining MoneyType value" is zero, assignment is complete. Skip the second layer.
- Otherwise, if the funds in the allocation are not completely depleted, error.
- Otherwise, for all other policy funds not in the allocation (second virtual layer)
- Order the policy's funds in this layer.
- For each fund,
- Calculated the prorata percentage: fund value / sum of cash values for funds in this layer.
- Apply the percentage to the layer's "remaining MoneyType value" and round to the currency rules. This is the fund's "removal amount".
- The last fund is adjusted so that the sum total of fund removals is equal to the layer's "remaining MoneyType value".
- For each fund in the layer in reverse order,
- If the fund's "removal amount" is greater than the fund's value, accumulate the difference and make "removal amount" equal to the fund's value. This is the "accumulated difference".
- If the fund's value is greater than its "removal amount", add as much of the "accumulated difference" to the "removal amount" as the fund's value will allow and adjust the "accumulated difference" by what the fund's value allowed.
- By the end of the loop, error if the "accumulated difference" is greater than 0.
- For each fund in the layer in original order,
- Calculate "allocation percent" as "removal amount" / "remaining MoneyType value".
- For the last fund, "allocation percent" is adjusted so the sum of all "allocation percents" is 1.
- For each non-zero value MoneyType in the order configured,
- For each fund in the layer in original order,
- if the last non-zero value MoneyType
- Calculate the amount to remove from the fund as the difference of fund's "removal amount" and the fund's "distributed amount".
- if the last non-zero value MoneyType
- otherwise,
- Calculate the fund's "removal amount" per MoneyType and round to the currency definition: "allocation percent" X MoneyType value.
- The last fund is adjusted so the sum of the "removal amount" values equals the MoneyType value.
- Accumulate the "removal amount". This is the "distributed amount".
- For each fund in the layer in original order,
The assignment's "remaining MoneyType value" is reduced by the layer's "remaining MoneyType value".
- If "remaining MoneyType value" is greater than 0, error.
- Otherwise,
- For each fund with a "removal amount" from any layer,
- An ending FundValue record is affected by the "removal amount".
- If tracking by fund, the "removal amount" is set into a FundValuationEffect record.
- "Remaining removal amount" is set to the fund's "removal amount".
- For each of the fund's deposit in LIFO or FIFO order,
- Calculate "deposit removal" as the lesser of the deposit's value and the fund's "remaining removal amount".
- Decrement the "remaining removal amount" by the "deposit removal".
- if the "remaining removal amount" is 0, looping through the deposits is complete.
- For each fund with a "removal amount" from any layer,
- If tracking funds by deposit,
- For each removal amount from a deposit,
- A new DepositValuationEffect record persists the amount of change in a fund’s value and maintains tracking by seed deposit, money type code, bucket (where applicable) and deposit date in the fund.
- If the fund is variable and the cash value of the remaining units is less than the smallest denomination of the currency, remove all units.
- A new DepositValuationEffect record persists the amount of change in a fund’s value and maintains tracking by seed deposit, money type code, bucket (where applicable) and deposit date in the fund.
- An ending DepositValue record is created to reflect the ending balances of the deposit’s CashValue, RawCashValue and Units.
- An ending record will exist for every beginning DepositValue record.
- The difference between beginning and ending record values is the change persisted in the DepositValuationEffect record for the same fund, seed deposit, money type code and deposit date.
- An ending FundValue record is created to reflect the ending balances of the fund's CashValue, RawCashValue and Units.
- If rounding level is deposit, CashValue is the sum of rounded cash value from the fund's ending DepositValue records.
- If rounding level is fund, CashValue is the sum of unrounded cash value from the fund's ending DepositValue records. The result is rounded to currency definition.
- Units and RawCashValue are the sum of the units and raw cash values, respectively, from the fund's ending DepositValue records.
- For each removal amount from a deposit,
- If not tracking funds by deposit,
- A FundValuationEffect record persists the amount of change in a fund’s value.
- If the fund is variable and the cash value of the remaining units is less than the smallest denomination of the currency, remove all units.
- An ending FundValue record is created to reflect the fund's ending balances.
- An ending record will exist for every beginning FundValue record.
- The difference between beginning and ending record values is the fund's changes persisted in the FundValuationEffect record.
- A FundValuationEffect record persists the amount of change in a fund’s value.